package cn.xxy.datasource;

import cn.xxy.beans.DataSourceConfig;

import javax.sql.DataSource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

public class DataSourceFactory {
	public static DataSource getDataSource(DataSourceConfig config) {
		return getDataSource(config.getDataSourceAdapter(), config);
	}
	public static DataSource getDataSource(String adapterClass, DataSourceConfig config) {
		if (adapterClass == null || "".equals(adapterClass)) throw new IllegalArgumentException("adapterClass");

		try {
			Class<?> clazz = Class.forName(adapterClass);
			if (!isDataSourceAdapter(clazz)) throw new IllegalArgumentException("adapterClass");

			DataSourceAdapter adapter = (DataSourceAdapter) clazz.getDeclaredConstructor().newInstance();
			return adapter.adapter(config);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static DataSource getDataSource(String configFile) {
		Map<String, String> config = loadConfigFile(configFile);

		String adapterClass = config.get("dataSourceAdapter");
		try {
			if (adapterClass == null || adapterClass.isEmpty()) throw new IllegalArgumentException("dataSourceAdapter");
			Class<?> clazz = Class.forName(adapterClass);
			if (!isDataSourceAdapter(clazz)) throw new IllegalArgumentException("dataSourceAdapter");

			DataSourceAdapter adapter = (DataSourceAdapter) clazz.getDeclaredConstructor().newInstance();
			return adapter.adapter(config);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private static Map<String, String> loadConfigFile(String configFile) {
		InputStream in = null;
		try {
			in = DataSourceFactory.class.getResourceAsStream(configFile);
			Map<String, String> result = new HashMap<String, String>();
			BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
			String line = null;
			while ((line = reader.readLine()) != null) {
				int index = line.indexOf("=");
				if (index == -1) result.put(line.trim(), null);
				else {
					result.put(line.substring(0, index).trim(), line.substring(index + 1).trim());
				}
			}
			return result;
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private static boolean isDataSourceAdapter(Class<?> clazz) {
		return DataSourceAdapter.class.isAssignableFrom(clazz);

	}
}
